package com.miyake.dsp.otdr;

import java.util.ArrayList;
import java.util.List;

import com.miyake.dsp.ComplexArray;
import com.miyake.dsp.Processor;
import com.miyake.dsp.ui.LineChartPanel;

public class SpliceDetector implements Processor {

	private SpliceDetectorSetting setting;
	private ComplexArray source;

	public SpliceDetector(SpliceDetectorSetting setting) {
		this.setting = setting;
	}
	
	@Override
	public void setSource(ComplexArray source) {
		this.source = source;
	}

	@Override
	public ComplexArray getSource() {
		return this.source;
	}

	private double getNoiseLevel() {
		double[] y = setting.getTrace();
		double peak = -10000;
		for (int i = y.length - 1; i > y.length - setting.getHold(); i--) {
			if (y[i] > peak) {
				peak = y[i];
			}
		}
		return peak;
	}
	
	private double getIncidentLevel() {
		double[] y = setting.getTrace();
		double peak = -1000;
		//for (int i = 0; i < setting.getHold() * 10; i++) {
		for (int i = 0; i < setting.getHold()*10; i++) {
		if (y[i] > peak) {
				peak = y[i];
			}
		}
		return peak;		
	}
	
	private List<Integer> getEvents() {
		boolean on = false;
		int count = 0;
		int current = 0;
		int pw = 1;
		double sum = 0;
		double[] y = this.setting.getTrace();
		double[] diff = source.getRealPart();
		List<Integer> events = new ArrayList<Integer>();
		
		double incident = getIncidentLevel();
		double noise = getNoiseLevel();
		
		double[] offset = new double[y.length];
		for (int i = 0; i < diff.length; i++) {
			//offset[i] = setting.getThreshold() / Math.pow(10, -(incident - y[i])/30);
			offset[i] = setting.getThreshold() + Math.pow(10, (noise-(y[i]-noise))/10);
			if (diff[i] >= offset[i] ) {
				if (!on) {
					current = i;
				}
				on = true;
				count++;
				events.add(i);
			}
			else {
				on = false;
				count = 0;
			}
			
			if (count == setting.getHold()) {
				events.add(current);
			}
		}
		LineChartPanel.showChart(offset, "Offset");
		return events;
	}
	
	@Override
	public ComplexArray getProcessed() {
		double[] ret = new double[source.getRealPart().length];
		List<Integer> list = getEvents();
		for (Integer i : list) {
			ret[i] = source.getRealPart()[i];
		}
		return new ComplexArray(ret);
	}

	@Override
	public Object getSetting() {
		return this.setting;
	}

}
